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.
This commit is contained in:
@@ -0,0 +1,172 @@
|
||||
using JdeScoping.DataSync.Services;
|
||||
|
||||
namespace JdeScoping.DataSync.Tests.Services;
|
||||
|
||||
public class MergeSqlBuilderTests
|
||||
{
|
||||
#region BuildCreateTempTable Tests
|
||||
|
||||
[Fact]
|
||||
public void BuildCreateTempTable_ValidInputs_ReturnsSelectInto()
|
||||
{
|
||||
// Act
|
||||
var sql = MergeSqlBuilder.BuildCreateTempTable("#TEMP_WorkOrder", "WorkOrder");
|
||||
|
||||
// Assert
|
||||
Assert.Equal("SELECT TOP 0 * INTO [#TEMP_WorkOrder] FROM [WorkOrder]", sql);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(null, "WorkOrder")]
|
||||
[InlineData("", "WorkOrder")]
|
||||
[InlineData("#TEMP", null)]
|
||||
[InlineData("#TEMP", "")]
|
||||
public void BuildCreateTempTable_InvalidInputs_ThrowsArgumentException(string? tempTable, string? sourceTable)
|
||||
{
|
||||
// Act & Assert
|
||||
Assert.ThrowsAny<ArgumentException>(() =>
|
||||
MergeSqlBuilder.BuildCreateTempTable(tempTable!, sourceTable!));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region BuildMergeSimple Tests
|
||||
|
||||
[Fact]
|
||||
public void BuildMergeSimple_SingleMatchColumn_BuildsCorrectMerge()
|
||||
{
|
||||
// Arrange
|
||||
var matchColumns = new[] { "Id" };
|
||||
var updateColumns = new[] { "Name", "Amount" };
|
||||
var insertColumns = new[] { "Id", "Name", "Amount" };
|
||||
|
||||
// Act
|
||||
var sql = MergeSqlBuilder.BuildMergeSimple(
|
||||
"TestTable", "#TEMP_TestTable",
|
||||
matchColumns, updateColumns, null, insertColumns);
|
||||
|
||||
// Assert
|
||||
Assert.Contains("MERGE INTO [TestTable] AS target", sql);
|
||||
Assert.Contains("USING [#TEMP_TestTable] AS source", sql);
|
||||
Assert.Contains("ON target.[Id] = source.[Id]", sql);
|
||||
Assert.Contains("WHEN MATCHED THEN", sql);
|
||||
Assert.Contains("UPDATE SET target.[Name] = source.[Name], target.[Amount] = source.[Amount]", sql);
|
||||
Assert.Contains("WHEN NOT MATCHED THEN", sql);
|
||||
Assert.Contains("INSERT ([Id], [Name], [Amount])", sql);
|
||||
Assert.Contains("VALUES (source.[Id], source.[Name], source.[Amount])", sql);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BuildMergeSimple_CompositeKey_BuildsCorrectOnClause()
|
||||
{
|
||||
// Arrange
|
||||
var matchColumns = new[] { "WorkOrderNumber", "BranchCode" };
|
||||
var updateColumns = new[] { "Status" };
|
||||
var insertColumns = new[] { "WorkOrderNumber", "BranchCode", "Status" };
|
||||
|
||||
// Act
|
||||
var sql = MergeSqlBuilder.BuildMergeSimple(
|
||||
"WorkOrder", "#TEMP",
|
||||
matchColumns, updateColumns, null, insertColumns);
|
||||
|
||||
// Assert
|
||||
Assert.Contains("ON target.[WorkOrderNumber] = source.[WorkOrderNumber] AND target.[BranchCode] = source.[BranchCode]", sql);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BuildMergeSimple_WithUpdateWhen_IncludesCondition()
|
||||
{
|
||||
// Arrange
|
||||
var matchColumns = new[] { "Id" };
|
||||
var updateColumns = new[] { "Name" };
|
||||
var insertColumns = new[] { "Id", "Name" };
|
||||
var updateWhen = "source.[LastUpdateDt] > target.[LastUpdateDt]";
|
||||
|
||||
// Act
|
||||
var sql = MergeSqlBuilder.BuildMergeSimple(
|
||||
"TestTable", "#TEMP",
|
||||
matchColumns, updateColumns, updateWhen, insertColumns);
|
||||
|
||||
// Assert
|
||||
Assert.Contains("WHEN MATCHED AND source.[LastUpdateDt] > target.[LastUpdateDt] THEN", sql);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BuildMergeSimple_NoUpdateColumns_OmitsUpdateClause()
|
||||
{
|
||||
// Arrange
|
||||
var matchColumns = new[] { "Id" };
|
||||
var updateColumns = Array.Empty<string>();
|
||||
var insertColumns = new[] { "Id", "Name" };
|
||||
|
||||
// Act
|
||||
var sql = MergeSqlBuilder.BuildMergeSimple(
|
||||
"TestTable", "#TEMP",
|
||||
matchColumns, updateColumns, null, insertColumns);
|
||||
|
||||
// Assert
|
||||
Assert.DoesNotContain("WHEN MATCHED", sql);
|
||||
Assert.Contains("WHEN NOT MATCHED THEN", sql);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BuildMergeSimple_EmptyMatchColumns_ThrowsArgumentException()
|
||||
{
|
||||
// Arrange
|
||||
var matchColumns = Array.Empty<string>();
|
||||
var updateColumns = new[] { "Name" };
|
||||
var insertColumns = new[] { "Id", "Name" };
|
||||
|
||||
// Act & Assert
|
||||
Assert.Throws<ArgumentException>(() =>
|
||||
MergeSqlBuilder.BuildMergeSimple(
|
||||
"TestTable", "#TEMP",
|
||||
matchColumns, updateColumns, null, insertColumns));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BuildMergeSimple_EmptyInsertColumns_ThrowsArgumentException()
|
||||
{
|
||||
// Arrange
|
||||
var matchColumns = new[] { "Id" };
|
||||
var updateColumns = new[] { "Name" };
|
||||
var insertColumns = Array.Empty<string>();
|
||||
|
||||
// Act & Assert
|
||||
Assert.Throws<ArgumentException>(() =>
|
||||
MergeSqlBuilder.BuildMergeSimple(
|
||||
"TestTable", "#TEMP",
|
||||
matchColumns, updateColumns, null, insertColumns));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region BuildTruncateTempTable Tests
|
||||
|
||||
[Fact]
|
||||
public void BuildTruncateTempTable_ValidInput_ReturnsTruncate()
|
||||
{
|
||||
// Act
|
||||
var sql = MergeSqlBuilder.BuildTruncateTempTable("#TEMP_WorkOrder");
|
||||
|
||||
// Assert
|
||||
Assert.Equal("TRUNCATE TABLE [#TEMP_WorkOrder]", sql);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region BuildDropTempTable Tests
|
||||
|
||||
[Fact]
|
||||
public void BuildDropTempTable_ValidInput_ReturnsDropWithCheck()
|
||||
{
|
||||
// Act
|
||||
var sql = MergeSqlBuilder.BuildDropTempTable("#TEMP_WorkOrder");
|
||||
|
||||
// Assert
|
||||
Assert.Contains("IF OBJECT_ID('tempdb..#TEMP_WorkOrder') IS NOT NULL", sql);
|
||||
Assert.Contains("DROP TABLE [#TEMP_WorkOrder]", sql);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
Reference in New Issue
Block a user