Files
jdescopingtool/NEW/tests/JdeScoping.DataAccess.Tests/DbConnectionFactoryTests.cs
T
Joseph Doherty 26ff8d9b4f Initial commit: JDE Scoping Tool migration project
Set up repository with legacy .NET Framework 4.8 source (OLD/),
new .NET 10 Blazor solution (NEW/), OpenSpec specifications,
documentation, and project configuration.
2026-01-02 07:43:29 -05:00

235 lines
7.7 KiB
C#

using JdeScoping.DataAccess.Exceptions;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using NSubstitute;
using Shouldly;
using Xunit;
namespace JdeScoping.DataAccess.Tests;
/// <summary>
/// Unit tests for DbConnectionFactory.
/// </summary>
public class DbConnectionFactoryTests
{
private readonly IConfiguration _configuration;
private readonly ILogger<DbConnectionFactory> _logger;
public DbConnectionFactoryTests()
{
_configuration = Substitute.For<IConfiguration>();
_logger = Substitute.For<ILogger<DbConnectionFactory>>();
}
#region Constructor Tests
[Fact]
public void Constructor_NullConfiguration_ThrowsArgumentNullException()
{
// Act & Assert
Should.Throw<ArgumentNullException>(() => new DbConnectionFactory(null!, _logger))
.ParamName.ShouldBe("configuration");
}
[Fact]
public void Constructor_NullLogger_ThrowsArgumentNullException()
{
// Act & Assert
Should.Throw<ArgumentNullException>(() => new DbConnectionFactory(_configuration, null!))
.ParamName.ShouldBe("logger");
}
[Fact]
public void Constructor_ValidParameters_CreatesInstance()
{
// Act
var factory = new DbConnectionFactory(_configuration, _logger);
// Assert
factory.ShouldNotBeNull();
}
#endregion
#region CreateLotFinderConnectionAsync Tests
[Fact]
public async Task CreateLotFinderConnectionAsync_MissingConnectionString_ThrowsConnectionException()
{
// Arrange
_configuration.GetConnectionString("LotFinderDB").Returns((string?)null);
var factory = new DbConnectionFactory(_configuration, _logger);
// Act & Assert
var ex = await Should.ThrowAsync<ConnectionException>(
async () => await factory.CreateLotFinderConnectionAsync());
ex.DataSource.ShouldBe("LotFinderDB");
ex.Message.ShouldContain("Connection string not found");
}
[Fact]
public async Task CreateLotFinderConnectionAsync_EmptyConnectionString_ThrowsConnectionException()
{
// Arrange
_configuration.GetConnectionString("LotFinderDB").Returns(string.Empty);
var factory = new DbConnectionFactory(_configuration, _logger);
// Act & Assert
var ex = await Should.ThrowAsync<ConnectionException>(
async () => await factory.CreateLotFinderConnectionAsync());
ex.DataSource.ShouldBe("LotFinderDB");
ex.Message.ShouldContain("Connection string not found");
}
[Fact]
public async Task CreateLotFinderConnectionAsync_InvalidConnectionString_ThrowsConnectionException()
{
// Arrange
_configuration.GetConnectionString("LotFinderDB").Returns("Invalid connection string");
var factory = new DbConnectionFactory(_configuration, _logger);
// Act & Assert
var ex = await Should.ThrowAsync<ConnectionException>(
async () => await factory.CreateLotFinderConnectionAsync());
ex.DataSource.ShouldBe("LotFinderDB");
ex.Message.ShouldContain("Failed to open connection");
ex.InnerException.ShouldNotBeNull();
}
[Fact]
public async Task CreateLotFinderConnectionAsync_CancellationRequested_ThrowsOperationCanceledException()
{
// Arrange
_configuration.GetConnectionString("LotFinderDB").Returns("Server=test;Database=test;");
var factory = new DbConnectionFactory(_configuration, _logger);
using var cts = new CancellationTokenSource();
cts.Cancel();
// Act & Assert
await Should.ThrowAsync<OperationCanceledException>(
async () => await factory.CreateLotFinderConnectionAsync(cts.Token));
}
#endregion
#region CreateJdeConnectionAsync Tests
[Fact]
public async Task CreateJdeConnectionAsync_MissingConnectionString_ThrowsConnectionException()
{
// Arrange
_configuration.GetConnectionString("JDE").Returns((string?)null);
var factory = new DbConnectionFactory(_configuration, _logger);
// Act & Assert
var ex = await Should.ThrowAsync<ConnectionException>(
async () => await factory.CreateJdeConnectionAsync());
ex.DataSource.ShouldBe("JDE");
ex.Message.ShouldContain("Connection string not found");
}
[Fact]
public async Task CreateJdeConnectionAsync_InvalidConnectionString_ThrowsConnectionException()
{
// Arrange
_configuration.GetConnectionString("JDE").Returns("Invalid oracle connection");
var factory = new DbConnectionFactory(_configuration, _logger);
// Act & Assert
var ex = await Should.ThrowAsync<ConnectionException>(
async () => await factory.CreateJdeConnectionAsync());
ex.DataSource.ShouldBe("JDE");
ex.Message.ShouldContain("Failed to open connection");
}
#endregion
#region CreateJdeStageConnectionAsync Tests
[Fact]
public async Task CreateJdeStageConnectionAsync_MissingConnectionString_ThrowsConnectionException()
{
// Arrange
_configuration.GetConnectionString("JDEStage").Returns((string?)null);
var factory = new DbConnectionFactory(_configuration, _logger);
// Act & Assert
var ex = await Should.ThrowAsync<ConnectionException>(
async () => await factory.CreateJdeStageConnectionAsync());
ex.DataSource.ShouldBe("JDEStage");
ex.Message.ShouldContain("Connection string not found");
}
#endregion
#region CreateCmsConnectionAsync Tests
[Fact]
public async Task CreateCmsConnectionAsync_MissingConnectionString_ThrowsConnectionException()
{
// Arrange
_configuration.GetConnectionString("CMS").Returns((string?)null);
var factory = new DbConnectionFactory(_configuration, _logger);
// Act & Assert
var ex = await Should.ThrowAsync<ConnectionException>(
async () => await factory.CreateCmsConnectionAsync());
ex.DataSource.ShouldBe("CMS");
ex.Message.ShouldContain("Connection string not found");
}
[Fact]
public async Task CreateCmsConnectionAsync_InvalidConnectionString_ThrowsConnectionException()
{
// Arrange
_configuration.GetConnectionString("CMS").Returns("Invalid oracle connection");
var factory = new DbConnectionFactory(_configuration, _logger);
// Act & Assert
var ex = await Should.ThrowAsync<ConnectionException>(
async () => await factory.CreateCmsConnectionAsync());
ex.DataSource.ShouldBe("CMS");
ex.Message.ShouldContain("Failed to open connection");
}
#endregion
#region Logging Tests
[Fact]
public async Task CreateLotFinderConnectionAsync_InvalidConnection_LogsError()
{
// Arrange
_configuration.GetConnectionString("LotFinderDB").Returns("Invalid connection string");
var factory = new DbConnectionFactory(_configuration, _logger);
// Act
try
{
await factory.CreateLotFinderConnectionAsync();
}
catch (ConnectionException)
{
// Expected
}
// Assert - verify error logging was called (at least once - there may also be debug logs)
_logger.Received().Log(
LogLevel.Error,
Arg.Any<EventId>(),
Arg.Any<object>(),
Arg.Any<Exception>(),
Arg.Any<Func<object, Exception?, string>>());
}
#endregion
}