feat(configmanager): add dedicated SQL Server port control
Add SqlServerPort property to connection string editor for explicit port configuration, replacing the need to embed port in server name (e.g., localhost,1434). The port control generates the comma-separated format in the connection string but does not parse it back when loading existing connection strings.
This commit is contained in:
@@ -55,6 +55,11 @@ public class ConnectionStringEntry
|
||||
/// </summary>
|
||||
public string? ApplicationName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the SQL Server port number. When null, no port is specified.
|
||||
/// </summary>
|
||||
public int? SqlServerPort { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Oracle server host name or address.
|
||||
/// </summary>
|
||||
@@ -94,7 +99,12 @@ public class ConnectionStringEntry
|
||||
var parts = new List<string>();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(Server))
|
||||
parts.Add($"Server={Server}");
|
||||
{
|
||||
var serverValue = SqlServerPort.HasValue && SqlServerPort.Value > 0
|
||||
? $"{Server},{SqlServerPort.Value}"
|
||||
: Server;
|
||||
parts.Add($"Server={serverValue}");
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(Database))
|
||||
parts.Add($"Database={Database}");
|
||||
if (!string.IsNullOrWhiteSpace(UserId))
|
||||
|
||||
+78
-77
@@ -62,11 +62,11 @@ public class ConnectionStringsSectionConverter : JsonConverter<ConnectionStrings
|
||||
? reader.GetString()
|
||||
: null;
|
||||
|
||||
var entry = ParseConnectionString(propertyName, connectionString ?? string.Empty);
|
||||
section.Entries.Add(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
var entry = ParseConnectionString(propertyName, connectionString ?? string.Empty);
|
||||
section.Entries.Add(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return section;
|
||||
}
|
||||
@@ -94,57 +94,57 @@ public class ConnectionStringsSectionConverter : JsonConverter<ConnectionStrings
|
||||
/// <summary>
|
||||
/// Parses a connection string and attempts to detect the provider type.
|
||||
/// </summary>
|
||||
internal static ConnectionStringEntry ParseConnectionString(string name, string connectionString)
|
||||
{
|
||||
var entry = new ConnectionStringEntry
|
||||
{
|
||||
Name = name,
|
||||
RawConnectionString = connectionString
|
||||
};
|
||||
|
||||
// Try to detect provider and parse structured fields
|
||||
var parts = ParseConnectionStringParts(connectionString);
|
||||
|
||||
// Detect Oracle using HOST/Service Name/Port pattern (DDTek.Oracle style)
|
||||
var hasHost = parts.TryGetValue("host", out var host);
|
||||
var hasServiceName = parts.TryGetValue("service name", out var serviceName);
|
||||
var hasPort = parts.TryGetValue("port", out var portText);
|
||||
|
||||
if (hasHost || hasServiceName || hasPort)
|
||||
{
|
||||
entry.Provider = ConnectionProvider.Oracle;
|
||||
|
||||
if (hasHost && !string.IsNullOrEmpty(host))
|
||||
{
|
||||
entry.Host = host;
|
||||
}
|
||||
|
||||
if (hasServiceName && !string.IsNullOrEmpty(serviceName))
|
||||
{
|
||||
entry.ServiceName = serviceName;
|
||||
}
|
||||
|
||||
if (hasPort && !string.IsNullOrEmpty(portText) && int.TryParse(portText, out var port))
|
||||
{
|
||||
entry.Port = port;
|
||||
}
|
||||
|
||||
if (parts.TryGetValue("user id", out var oraUserId))
|
||||
{
|
||||
entry.UserId = oraUserId;
|
||||
}
|
||||
|
||||
if (parts.TryGetValue("password", out var oraPassword))
|
||||
{
|
||||
entry.Password = oraPassword;
|
||||
}
|
||||
}
|
||||
// Detect Oracle first (Data Source with host:port/service pattern)
|
||||
else if (parts.TryGetValue("data source", out var dataSource) &&
|
||||
IsOracleDataSource(dataSource))
|
||||
{
|
||||
entry.Provider = ConnectionProvider.Oracle;
|
||||
ParseOracleDataSource(entry, dataSource);
|
||||
internal static ConnectionStringEntry ParseConnectionString(string name, string connectionString)
|
||||
{
|
||||
var entry = new ConnectionStringEntry
|
||||
{
|
||||
Name = name,
|
||||
RawConnectionString = connectionString
|
||||
};
|
||||
|
||||
// Try to detect provider and parse structured fields
|
||||
var parts = ParseConnectionStringParts(connectionString);
|
||||
|
||||
// Detect Oracle using HOST/Service Name/Port pattern (DDTek.Oracle style)
|
||||
var hasHost = parts.TryGetValue("host", out var host);
|
||||
var hasServiceName = parts.TryGetValue("service name", out var serviceName);
|
||||
var hasPort = parts.TryGetValue("port", out var portText);
|
||||
|
||||
if (hasHost || hasServiceName || hasPort)
|
||||
{
|
||||
entry.Provider = ConnectionProvider.Oracle;
|
||||
|
||||
if (hasHost && !string.IsNullOrEmpty(host))
|
||||
{
|
||||
entry.Host = host;
|
||||
}
|
||||
|
||||
if (hasServiceName && !string.IsNullOrEmpty(serviceName))
|
||||
{
|
||||
entry.ServiceName = serviceName;
|
||||
}
|
||||
|
||||
if (hasPort && !string.IsNullOrEmpty(portText) && int.TryParse(portText, out var port))
|
||||
{
|
||||
entry.Port = port;
|
||||
}
|
||||
|
||||
if (parts.TryGetValue("user id", out var oraUserId))
|
||||
{
|
||||
entry.UserId = oraUserId;
|
||||
}
|
||||
|
||||
if (parts.TryGetValue("password", out var oraPassword))
|
||||
{
|
||||
entry.Password = oraPassword;
|
||||
}
|
||||
}
|
||||
// Detect Oracle first (Data Source with host:port/service pattern)
|
||||
else if (parts.TryGetValue("data source", out var dataSource) &&
|
||||
IsOracleDataSource(dataSource))
|
||||
{
|
||||
entry.Provider = ConnectionProvider.Oracle;
|
||||
ParseOracleDataSource(entry, dataSource);
|
||||
|
||||
if (parts.TryGetValue("user id", out var oraUserId))
|
||||
{
|
||||
@@ -212,27 +212,28 @@ public class ConnectionStringsSectionConverter : JsonConverter<ConnectionStrings
|
||||
entry.Provider = ConnectionProvider.Generic;
|
||||
}
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
internal static void ApplyConnectionString(ConnectionStringEntry entry, string connectionString)
|
||||
{
|
||||
var parsed = ParseConnectionString(entry.Name, connectionString);
|
||||
|
||||
entry.Provider = parsed.Provider;
|
||||
entry.Server = parsed.Server;
|
||||
entry.Database = parsed.Database;
|
||||
entry.UserId = parsed.UserId;
|
||||
entry.Password = parsed.Password;
|
||||
entry.Encrypt = parsed.Encrypt;
|
||||
entry.TrustServerCertificate = parsed.TrustServerCertificate;
|
||||
entry.ConnectionTimeout = parsed.ConnectionTimeout;
|
||||
entry.ApplicationName = parsed.ApplicationName;
|
||||
entry.Host = parsed.Host;
|
||||
entry.Port = parsed.Port;
|
||||
entry.ServiceName = parsed.ServiceName;
|
||||
entry.RawConnectionString = parsed.RawConnectionString;
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
|
||||
internal static void ApplyConnectionString(ConnectionStringEntry entry, string connectionString)
|
||||
{
|
||||
var parsed = ParseConnectionString(entry.Name, connectionString);
|
||||
|
||||
entry.Provider = parsed.Provider;
|
||||
entry.Server = parsed.Server;
|
||||
entry.SqlServerPort = parsed.SqlServerPort;
|
||||
entry.Database = parsed.Database;
|
||||
entry.UserId = parsed.UserId;
|
||||
entry.Password = parsed.Password;
|
||||
entry.Encrypt = parsed.Encrypt;
|
||||
entry.TrustServerCertificate = parsed.TrustServerCertificate;
|
||||
entry.ConnectionTimeout = parsed.ConnectionTimeout;
|
||||
entry.ApplicationName = parsed.ApplicationName;
|
||||
entry.Host = parsed.Host;
|
||||
entry.Port = parsed.Port;
|
||||
entry.ServiceName = parsed.ServiceName;
|
||||
entry.RawConnectionString = parsed.RawConnectionString;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses a connection string into key-value pairs.
|
||||
|
||||
+18
@@ -208,6 +208,24 @@ public class ConnectionStringEntryViewModel : ViewModelBase
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the SQL Server port number.
|
||||
/// </summary>
|
||||
public int? SqlServerPort
|
||||
{
|
||||
get => _model.SqlServerPort;
|
||||
set
|
||||
{
|
||||
if (_model.SqlServerPort != value)
|
||||
{
|
||||
_model.SqlServerPort = value;
|
||||
OnPropertyChanged();
|
||||
OnPropertyChanged(nameof(GeneratedConnectionString));
|
||||
_onChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Oracle host name.
|
||||
/// </summary>
|
||||
|
||||
+40
-28
@@ -10,8 +10,8 @@
|
||||
<!-- SqlServer Provider Template -->
|
||||
<DataTemplate x:Key="SqlServerTemplate" x:DataType="vm:ConnectionStringEntryViewModel">
|
||||
<StackPanel Spacing="16">
|
||||
<!-- Server & Database Row -->
|
||||
<Grid ColumnDefinitions="*,16,*">
|
||||
<!-- Server & Port Row -->
|
||||
<Grid ColumnDefinitions="*,16,120">
|
||||
<StackPanel Grid.Column="0" Spacing="4">
|
||||
<TextBlock Text="Server" Foreground="#9BA8B8" FontSize="12" FontWeight="Medium"/>
|
||||
<TextBox Text="{Binding Server}"
|
||||
@@ -23,15 +23,27 @@
|
||||
Foreground="#5C6A7A" FontSize="11"/>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Column="2" Spacing="4">
|
||||
<TextBlock Text="Database" Foreground="#9BA8B8" FontSize="12" FontWeight="Medium"/>
|
||||
<TextBox Text="{Binding Database}"
|
||||
Background="#232A35" Foreground="#E6EDF5"
|
||||
BorderBrush="#3D4550" Height="36"
|
||||
FontFamily="JetBrains Mono"
|
||||
Watermark="ScopingTool"/>
|
||||
<TextBlock Text="Port" Foreground="#9BA8B8" FontSize="12" FontWeight="Medium"/>
|
||||
<NumericUpDown Value="{Binding SqlServerPort}"
|
||||
Minimum="1" Maximum="65535"
|
||||
Background="#232A35" Foreground="#E6EDF5"
|
||||
BorderBrush="#3D4550" Height="36"
|
||||
FontFamily="JetBrains Mono"/>
|
||||
<TextBlock Text="Default: 1433"
|
||||
Foreground="#5C6A7A" FontSize="11"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
<!-- Database Row -->
|
||||
<StackPanel Spacing="4">
|
||||
<TextBlock Text="Database" Foreground="#9BA8B8" FontSize="12" FontWeight="Medium"/>
|
||||
<TextBox Text="{Binding Database}"
|
||||
Background="#232A35" Foreground="#E6EDF5"
|
||||
BorderBrush="#3D4550" Height="36"
|
||||
FontFamily="JetBrains Mono"
|
||||
Watermark="ScopingTool"/>
|
||||
</StackPanel>
|
||||
|
||||
<!-- UserId & Password Row -->
|
||||
<Grid ColumnDefinitions="*,16,*">
|
||||
<StackPanel Grid.Column="0" Spacing="4">
|
||||
@@ -279,26 +291,26 @@
|
||||
</Border>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Connection List -->
|
||||
<Border BorderBrush="#2D3540" BorderThickness="1" CornerRadius="4">
|
||||
<DataGrid ItemsSource="{Binding Connections}"
|
||||
SelectedItem="{Binding SelectedConnection}"
|
||||
AutoGenerateColumns="False"
|
||||
IsReadOnly="True"
|
||||
SelectionMode="Single"
|
||||
GridLinesVisibility="Horizontal"
|
||||
HeadersVisibility="Column"
|
||||
Background="#0D0F12"
|
||||
RowBackground="#0D0F12"
|
||||
MaxHeight="220"
|
||||
MinHeight="100">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Header="Name" Binding="{Binding Name}" Width="Auto"/>
|
||||
<DataGridTextColumn Header="Provider" Binding="{Binding ProviderDisplay}" Width="Auto"/>
|
||||
<DataGridTextColumn Header="Server" Binding="{Binding ServerDisplay}" Width="*"/>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
</Border>
|
||||
<!-- Connection List -->
|
||||
<Border BorderBrush="#2D3540" BorderThickness="1" CornerRadius="4">
|
||||
<DataGrid ItemsSource="{Binding Connections}"
|
||||
SelectedItem="{Binding SelectedConnection}"
|
||||
AutoGenerateColumns="False"
|
||||
IsReadOnly="True"
|
||||
SelectionMode="Single"
|
||||
GridLinesVisibility="Horizontal"
|
||||
HeadersVisibility="Column"
|
||||
Background="#0D0F12"
|
||||
RowBackground="#0D0F12"
|
||||
MaxHeight="220"
|
||||
MinHeight="100">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Header="Name" Binding="{Binding Name}" Width="Auto"/>
|
||||
<DataGridTextColumn Header="Provider" Binding="{Binding ProviderDisplay}" Width="Auto"/>
|
||||
<DataGridTextColumn Header="Server" Binding="{Binding ServerDisplay}" Width="*"/>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
</Border>
|
||||
|
||||
<!-- Toolbar -->
|
||||
<StackPanel Orientation="Horizontal" Spacing="8">
|
||||
|
||||
@@ -107,6 +107,7 @@ public class ConnectionStringEntryTests
|
||||
entry.Name.ShouldBe(string.Empty);
|
||||
entry.Provider.ShouldBe(ConnectionProvider.Generic);
|
||||
entry.Server.ShouldBeNull();
|
||||
entry.SqlServerPort.ShouldBeNull();
|
||||
entry.Database.ShouldBeNull();
|
||||
entry.UserId.ShouldBeNull();
|
||||
entry.Password.ShouldBeNull();
|
||||
@@ -119,4 +120,70 @@ public class ConnectionStringEntryTests
|
||||
entry.ServiceName.ShouldBeNull();
|
||||
entry.RawConnectionString.ShouldBeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GenerateConnectionString_SqlServer_WithPort_IncludesPortInServer()
|
||||
{
|
||||
// Arrange
|
||||
var entry = new ConnectionStringEntry
|
||||
{
|
||||
Provider = ConnectionProvider.SqlServer,
|
||||
Server = "localhost",
|
||||
SqlServerPort = 1434,
|
||||
Database = "TestDb",
|
||||
UserId = "sa",
|
||||
Password = "secret123"
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = entry.GenerateConnectionString();
|
||||
|
||||
// Assert
|
||||
result.ShouldContain("Server=localhost,1434");
|
||||
result.ShouldContain("Database=TestDb");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GenerateConnectionString_SqlServer_WithoutPort_NoPortInServer()
|
||||
{
|
||||
// Arrange
|
||||
var entry = new ConnectionStringEntry
|
||||
{
|
||||
Provider = ConnectionProvider.SqlServer,
|
||||
Server = "localhost",
|
||||
SqlServerPort = null,
|
||||
Database = "TestDb",
|
||||
UserId = "sa",
|
||||
Password = "secret123"
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = entry.GenerateConnectionString();
|
||||
|
||||
// Assert
|
||||
result.ShouldContain("Server=localhost;");
|
||||
result.ShouldNotContain("Server=localhost,");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GenerateConnectionString_SqlServer_WithZeroPort_NoPortInServer()
|
||||
{
|
||||
// Arrange
|
||||
var entry = new ConnectionStringEntry
|
||||
{
|
||||
Provider = ConnectionProvider.SqlServer,
|
||||
Server = "localhost",
|
||||
SqlServerPort = 0,
|
||||
Database = "TestDb",
|
||||
UserId = "sa",
|
||||
Password = "secret123"
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = entry.GenerateConnectionString();
|
||||
|
||||
// Assert
|
||||
result.ShouldContain("Server=localhost;");
|
||||
result.ShouldNotContain("Server=localhost,");
|
||||
}
|
||||
}
|
||||
|
||||
+81
-1
@@ -34,7 +34,8 @@ public class ConnectionStringsSectionConverterTests
|
||||
|
||||
var lotFinder = section.Entries.First(e => e.Name == "LotFinder");
|
||||
lotFinder.Provider.ShouldBe(ConnectionProvider.SqlServer);
|
||||
lotFinder.Server.ShouldBe("localhost,1434");
|
||||
lotFinder.Server.ShouldBe("localhost,1434"); // Port embedded in server, not parsed separately
|
||||
lotFinder.SqlServerPort.ShouldBeNull();
|
||||
lotFinder.Database.ShouldBe("ScopingTool");
|
||||
lotFinder.UserId.ShouldBe("sa");
|
||||
|
||||
@@ -195,4 +196,83 @@ public class ConnectionStringsSectionConverterTests
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
+37
@@ -14,6 +14,7 @@ public class ConnectionStringEntryViewModelTests
|
||||
Name = "TestConnection",
|
||||
Provider = ConnectionProvider.SqlServer,
|
||||
Server = "localhost",
|
||||
SqlServerPort = 1434,
|
||||
Database = "TestDb",
|
||||
UserId = "testuser",
|
||||
Password = "testpass",
|
||||
@@ -30,6 +31,7 @@ public class ConnectionStringEntryViewModelTests
|
||||
sut.Name.ShouldBe("TestConnection");
|
||||
sut.Provider.ShouldBe(ConnectionProvider.SqlServer);
|
||||
sut.Server.ShouldBe("localhost");
|
||||
sut.SqlServerPort.ShouldBe(1434);
|
||||
sut.Database.ShouldBe("TestDb");
|
||||
sut.UserId.ShouldBe("testuser");
|
||||
sut.Password.ShouldBe("testpass");
|
||||
@@ -179,4 +181,39 @@ public class ConnectionStringEntryViewModelTests
|
||||
// Assert
|
||||
sut.ServerDisplay.ShouldBe("-");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SqlServerPort_PropertyChange_UpdatesModel()
|
||||
{
|
||||
// Arrange
|
||||
var model = new ConnectionStringEntry();
|
||||
var changedInvoked = false;
|
||||
var sut = new ConnectionStringEntryViewModel(model, () => changedInvoked = true);
|
||||
|
||||
// Act
|
||||
sut.SqlServerPort = 1434;
|
||||
|
||||
// Assert
|
||||
model.SqlServerPort.ShouldBe(1434);
|
||||
changedInvoked.ShouldBeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SqlServerPort_PropertyChange_UpdatesGeneratedConnectionString()
|
||||
{
|
||||
// Arrange
|
||||
var model = new ConnectionStringEntry
|
||||
{
|
||||
Provider = ConnectionProvider.SqlServer,
|
||||
Server = "localhost",
|
||||
Database = "TestDb"
|
||||
};
|
||||
var sut = new ConnectionStringEntryViewModel(model, () => { });
|
||||
|
||||
// Act
|
||||
sut.SqlServerPort = 1434;
|
||||
|
||||
// Assert
|
||||
sut.GeneratedConnectionString.ShouldContain("Server=localhost,1434");
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -75,10 +75,11 @@ public class ConnectionStringsFormViewModelTests
|
||||
// Act
|
||||
var sut = new ConnectionStringsFormViewModel(model, _secureStoreManager, () => { }, _dialogService, _connectionTestService);
|
||||
|
||||
// Assert
|
||||
// Assert - port stays embedded in server name, not parsed into SqlServerPort
|
||||
sut.Connections.Count.ShouldBe(1);
|
||||
sut.Connections[0].Provider.ShouldBe(ConnectionProvider.SqlServer);
|
||||
sut.Connections[0].Server.ShouldBe("localhost,1434");
|
||||
sut.Connections[0].SqlServerPort.ShouldBeNull();
|
||||
sut.Connections[0].Database.ShouldBe("ScopingTool");
|
||||
sut.Connections[0].UserId.ShouldBe("scopingapp");
|
||||
sut.Connections[0].Password.ShouldBe("pass");
|
||||
|
||||
Reference in New Issue
Block a user