feat(datasync): add generic DbQuerySource for JDE/CMS/LotFinder
Extend DbQuerySource to support multiple connection types:
- Add connectionType parameter ("jde", "cms", "lotfinder")
- Use appropriate IDbConnectionFactory method for each type
- Support Dictionary<string, object> parameters
- Use DbConnection/DbCommand for cross-database compatibility
This commit is contained in:
@@ -1,44 +1,84 @@
|
||||
using JdeScoping.DataAccess.Interfaces;
|
||||
using JdeScoping.DataSync.Etl.Sources;
|
||||
using NSubstitute;
|
||||
using Shouldly;
|
||||
|
||||
namespace JdeScoping.DataSync.Tests.Etl.Sources;
|
||||
|
||||
public class DbQuerySourceTests
|
||||
{
|
||||
[Fact]
|
||||
public void Constructor_SetsSourceName()
|
||||
[Theory]
|
||||
[InlineData("jde")]
|
||||
[InlineData("cms")]
|
||||
[InlineData("lotfinder")]
|
||||
public void Constructor_ValidConnectionType_Succeeds(string connectionType)
|
||||
{
|
||||
var factory = Substitute.For<IDbConnectionFactory>();
|
||||
var source = new DbQuerySource(factory, "SELECT 1", "TestSource");
|
||||
Assert.Equal("DbQuery:TestSource", source.SourceName);
|
||||
var source = new DbQuerySource(factory, connectionType, "SELECT 1");
|
||||
source.SourceName.ShouldBe($"DbQuery:{connectionType}");
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("JDE")]
|
||||
[InlineData("CMS")]
|
||||
[InlineData("LotFinder")]
|
||||
[InlineData("LOTFINDER")]
|
||||
public void Constructor_ConnectionType_IsCaseInsensitive(string connectionType)
|
||||
{
|
||||
var factory = Substitute.For<IDbConnectionFactory>();
|
||||
var source = new DbQuerySource(factory, connectionType, "SELECT 1");
|
||||
source.SourceName.ShouldBe($"DbQuery:{connectionType.ToLowerInvariant()}");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Constructor_NullName_UsesDefault()
|
||||
public void Constructor_InvalidConnectionType_Throws()
|
||||
{
|
||||
var factory = Substitute.For<IDbConnectionFactory>();
|
||||
var source = new DbQuerySource(factory, "SELECT 1");
|
||||
Assert.Equal("DbQuery:Query", source.SourceName);
|
||||
Should.Throw<ArgumentException>(() =>
|
||||
new DbQuerySource(factory, "invalid", "SELECT 1"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Constructor_NullConnectionType_Throws()
|
||||
{
|
||||
var factory = Substitute.For<IDbConnectionFactory>();
|
||||
Should.Throw<ArgumentNullException>(() =>
|
||||
new DbQuerySource(factory, null!, "SELECT 1"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Constructor_NullQuery_Throws()
|
||||
{
|
||||
var factory = Substitute.For<IDbConnectionFactory>();
|
||||
Should.Throw<ArgumentNullException>(() =>
|
||||
new DbQuerySource(factory, "jde", null!));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Constructor_NullFactory_ThrowsArgumentNullException()
|
||||
{
|
||||
Assert.Throws<ArgumentNullException>(() => new DbQuerySource(null!, "SELECT 1"));
|
||||
Assert.Throws<ArgumentNullException>(() => new DbQuerySource(null!, "jde", "SELECT 1"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Constructor_NullSql_ThrowsArgumentNullException()
|
||||
public void Constructor_WithParameters_Succeeds()
|
||||
{
|
||||
var factory = Substitute.For<IDbConnectionFactory>();
|
||||
Assert.Throws<ArgumentNullException>(() => new DbQuerySource(factory, null!));
|
||||
var parameters = new Dictionary<string, object>
|
||||
{
|
||||
{ "MinDate", DateTime.Now },
|
||||
{ "Status", 1 }
|
||||
};
|
||||
|
||||
var source = new DbQuerySource(factory, "lotfinder", "SELECT * FROM T WHERE Date > @MinDate AND Status = @Status", parameters);
|
||||
source.SourceName.ShouldBe("DbQuery:lotfinder");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Constructor_EmptySql_ThrowsArgumentException()
|
||||
public void Constructor_WithCustomTimeout_Succeeds()
|
||||
{
|
||||
var factory = Substitute.For<IDbConnectionFactory>();
|
||||
Assert.Throws<ArgumentException>(() => new DbQuerySource(factory, ""));
|
||||
var source = new DbQuerySource(factory, "jde", "SELECT 1", commandTimeout: 7200);
|
||||
source.SourceName.ShouldBe("DbQuery:jde");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user