26ff8d9b4f
Set up repository with legacy .NET Framework 4.8 source (OLD/), new .NET 10 Blazor solution (NEW/), OpenSpec specifications, documentation, and project configuration.
173 lines
5.5 KiB
C#
173 lines
5.5 KiB
C#
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
|
|
}
|