test(db): add complex table extraction function tests
This commit is contained in:
@@ -0,0 +1,514 @@
|
||||
using Dapper;
|
||||
using FluentAssertions;
|
||||
using JdeScoping.Core.Models.Search;
|
||||
using JdeScoping.Core.ViewModels;
|
||||
using JdeScoping.Database.Tests.Infrastructure;
|
||||
|
||||
namespace JdeScoping.Database.Tests.Functions;
|
||||
|
||||
/// <summary>
|
||||
/// Tests for complex table extraction functions that return multi-column result sets.
|
||||
/// These inline TVFs extract object arrays from Search.Criteria JSON:
|
||||
/// - fn_GetSearchComponentLots: returns (LotNumber, ItemNumber)
|
||||
/// - fn_GetSearchPartOperations: returns (ItemNumber, OperationNumber, MisNumber, MisRevision)
|
||||
/// </summary>
|
||||
[Collection("DatabaseTests")]
|
||||
public class ComplexTableFunctionTests : DatabaseTestBase
|
||||
{
|
||||
#region fn_GetSearchComponentLots Tests
|
||||
|
||||
[Fact]
|
||||
public async Task fn_GetSearchComponentLots_ValidArray_ReturnsAllRowsWithAllColumns()
|
||||
{
|
||||
// Arrange
|
||||
var criteria = new SearchCriteria
|
||||
{
|
||||
ComponentLotNumbers =
|
||||
[
|
||||
new LotViewModel { LotNumber = "LOT001", ItemNumber = "ITEM001" },
|
||||
new LotViewModel { LotNumber = "LOT002", ItemNumber = "ITEM002" },
|
||||
new LotViewModel { LotNumber = "LOT003", ItemNumber = "ITEM003" }
|
||||
]
|
||||
};
|
||||
var searchId = await InsertTestSearchAsync(criteria);
|
||||
|
||||
// Act
|
||||
var results = await Connection.QueryAsync<(string LotNumber, string ItemNumber)>(
|
||||
"SELECT LotNumber, ItemNumber FROM dbo.fn_GetSearchComponentLots(@SearchId)",
|
||||
new { SearchId = searchId });
|
||||
|
||||
// Assert
|
||||
var resultList = results.ToList();
|
||||
resultList.Should().HaveCount(3);
|
||||
resultList.Should().Contain(x => x.LotNumber == "LOT001" && x.ItemNumber == "ITEM001");
|
||||
resultList.Should().Contain(x => x.LotNumber == "LOT002" && x.ItemNumber == "ITEM002");
|
||||
resultList.Should().Contain(x => x.LotNumber == "LOT003" && x.ItemNumber == "ITEM003");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task fn_GetSearchComponentLots_EmptyArray_ReturnsEmpty()
|
||||
{
|
||||
// Arrange
|
||||
var criteria = new SearchCriteria { ComponentLotNumbers = [] };
|
||||
var searchId = await InsertTestSearchAsync(criteria);
|
||||
|
||||
// Act
|
||||
var results = await Connection.QueryAsync<(string LotNumber, string ItemNumber)>(
|
||||
"SELECT LotNumber, ItemNumber FROM dbo.fn_GetSearchComponentLots(@SearchId)",
|
||||
new { SearchId = searchId });
|
||||
|
||||
// Assert
|
||||
results.Should().BeEmpty();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task fn_GetSearchComponentLots_MissingProperty_ReturnsEmpty()
|
||||
{
|
||||
// Arrange - criteria without ComponentLotNumbers property
|
||||
var searchId = await InsertTestSearchWithRawCriteriaAsync("{\"MinimumDt\":null}");
|
||||
|
||||
// Act
|
||||
var results = await Connection.QueryAsync<(string LotNumber, string ItemNumber)>(
|
||||
"SELECT LotNumber, ItemNumber FROM dbo.fn_GetSearchComponentLots(@SearchId)",
|
||||
new { SearchId = searchId });
|
||||
|
||||
// Assert
|
||||
results.Should().BeEmpty();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task fn_GetSearchComponentLots_SearchNotFound_ReturnsEmpty()
|
||||
{
|
||||
// Act
|
||||
var results = await Connection.QueryAsync<(string LotNumber, string ItemNumber)>(
|
||||
"SELECT LotNumber, ItemNumber FROM dbo.fn_GetSearchComponentLots(@SearchId)",
|
||||
new { SearchId = 99999 });
|
||||
|
||||
// Assert
|
||||
results.Should().BeEmpty();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task fn_GetSearchComponentLots_NullCriteria_ReturnsEmpty()
|
||||
{
|
||||
// Arrange
|
||||
var searchId = await InsertTestSearchWithRawCriteriaAsync(null);
|
||||
|
||||
// Act
|
||||
var results = await Connection.QueryAsync<(string LotNumber, string ItemNumber)>(
|
||||
"SELECT LotNumber, ItemNumber FROM dbo.fn_GetSearchComponentLots(@SearchId)",
|
||||
new { SearchId = searchId });
|
||||
|
||||
// Assert
|
||||
results.Should().BeEmpty();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task fn_GetSearchComponentLots_InvalidJson_ReturnsEmpty()
|
||||
{
|
||||
// Arrange
|
||||
var searchId = await InsertTestSearchWithRawCriteriaAsync("not valid json");
|
||||
|
||||
// Act
|
||||
var results = await Connection.QueryAsync<(string LotNumber, string ItemNumber)>(
|
||||
"SELECT LotNumber, ItemNumber FROM dbo.fn_GetSearchComponentLots(@SearchId)",
|
||||
new { SearchId = searchId });
|
||||
|
||||
// Assert
|
||||
results.Should().BeEmpty();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task fn_GetSearchComponentLots_PartialObjects_UsesNullForMissingColumns()
|
||||
{
|
||||
// Arrange - JSON with objects missing some properties
|
||||
var searchId = await InsertTestSearchWithRawCriteriaAsync(
|
||||
"{\"ComponentLotNumbers\":[" +
|
||||
"{\"LotNumber\":\"LOT001\"}," + // Missing ItemNumber
|
||||
"{\"ItemNumber\":\"ITEM002\"}," + // Missing LotNumber
|
||||
"{\"LotNumber\":\"LOT003\",\"ItemNumber\":\"ITEM003\"}" + // Complete
|
||||
"]}");
|
||||
|
||||
// Act
|
||||
var results = await Connection.QueryAsync<(string? LotNumber, string? ItemNumber)>(
|
||||
"SELECT LotNumber, ItemNumber FROM dbo.fn_GetSearchComponentLots(@SearchId)",
|
||||
new { SearchId = searchId });
|
||||
|
||||
// Assert
|
||||
var resultList = results.ToList();
|
||||
resultList.Should().HaveCount(3);
|
||||
resultList.Should().Contain(x => x.LotNumber == "LOT001" && x.ItemNumber == null);
|
||||
resultList.Should().Contain(x => x.LotNumber == null && x.ItemNumber == "ITEM002");
|
||||
resultList.Should().Contain(x => x.LotNumber == "LOT003" && x.ItemNumber == "ITEM003");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task fn_GetSearchComponentLots_SpecialCharacters_ReturnsCorrectly()
|
||||
{
|
||||
// Arrange
|
||||
var criteria = new SearchCriteria
|
||||
{
|
||||
ComponentLotNumbers =
|
||||
[
|
||||
new LotViewModel { LotNumber = "LOT-001", ItemNumber = "ITEM_001" },
|
||||
new LotViewModel { LotNumber = "LOT.002", ItemNumber = "ITEM/002" }
|
||||
]
|
||||
};
|
||||
var searchId = await InsertTestSearchAsync(criteria);
|
||||
|
||||
// Act
|
||||
var results = await Connection.QueryAsync<(string LotNumber, string ItemNumber)>(
|
||||
"SELECT LotNumber, ItemNumber FROM dbo.fn_GetSearchComponentLots(@SearchId)",
|
||||
new { SearchId = searchId });
|
||||
|
||||
// Assert
|
||||
var resultList = results.ToList();
|
||||
resultList.Should().HaveCount(2);
|
||||
resultList.Should().Contain(x => x.LotNumber == "LOT-001" && x.ItemNumber == "ITEM_001");
|
||||
resultList.Should().Contain(x => x.LotNumber == "LOT.002" && x.ItemNumber == "ITEM/002");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region fn_GetSearchPartOperations Tests
|
||||
|
||||
[Fact]
|
||||
public async Task fn_GetSearchPartOperations_ValidArray_ReturnsAllRowsWithAllColumns()
|
||||
{
|
||||
// Arrange
|
||||
var criteria = new SearchCriteria
|
||||
{
|
||||
PartOperations =
|
||||
[
|
||||
new PartOperationViewModel
|
||||
{
|
||||
ItemNumber = "ITEM001",
|
||||
OperationNumber = "10",
|
||||
MisNumber = "MIS001",
|
||||
MisRevision = "A"
|
||||
},
|
||||
new PartOperationViewModel
|
||||
{
|
||||
ItemNumber = "ITEM002",
|
||||
OperationNumber = "20",
|
||||
MisNumber = "MIS002",
|
||||
MisRevision = "B"
|
||||
},
|
||||
new PartOperationViewModel
|
||||
{
|
||||
ItemNumber = "ITEM003",
|
||||
OperationNumber = "30",
|
||||
MisNumber = "MIS003",
|
||||
MisRevision = "C"
|
||||
}
|
||||
]
|
||||
};
|
||||
var searchId = await InsertTestSearchAsync(criteria);
|
||||
|
||||
// Act
|
||||
var results = await Connection.QueryAsync<(string ItemNumber, string OperationNumber, string MisNumber, string MisRevision)>(
|
||||
"SELECT ItemNumber, OperationNumber, MisNumber, MisRevision FROM dbo.fn_GetSearchPartOperations(@SearchId)",
|
||||
new { SearchId = searchId });
|
||||
|
||||
// Assert
|
||||
var resultList = results.ToList();
|
||||
resultList.Should().HaveCount(3);
|
||||
resultList.Should().Contain(x => x.ItemNumber == "ITEM001" && x.OperationNumber == "10" && x.MisNumber == "MIS001" && x.MisRevision == "A");
|
||||
resultList.Should().Contain(x => x.ItemNumber == "ITEM002" && x.OperationNumber == "20" && x.MisNumber == "MIS002" && x.MisRevision == "B");
|
||||
resultList.Should().Contain(x => x.ItemNumber == "ITEM003" && x.OperationNumber == "30" && x.MisNumber == "MIS003" && x.MisRevision == "C");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task fn_GetSearchPartOperations_EmptyArray_ReturnsEmpty()
|
||||
{
|
||||
// Arrange
|
||||
var criteria = new SearchCriteria { PartOperations = [] };
|
||||
var searchId = await InsertTestSearchAsync(criteria);
|
||||
|
||||
// Act
|
||||
var results = await Connection.QueryAsync<(string ItemNumber, string OperationNumber, string MisNumber, string MisRevision)>(
|
||||
"SELECT ItemNumber, OperationNumber, MisNumber, MisRevision FROM dbo.fn_GetSearchPartOperations(@SearchId)",
|
||||
new { SearchId = searchId });
|
||||
|
||||
// Assert
|
||||
results.Should().BeEmpty();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task fn_GetSearchPartOperations_MissingProperty_ReturnsEmpty()
|
||||
{
|
||||
// Arrange - criteria without PartOperations property
|
||||
var searchId = await InsertTestSearchWithRawCriteriaAsync("{\"MinimumDt\":null}");
|
||||
|
||||
// Act
|
||||
var results = await Connection.QueryAsync<(string ItemNumber, string OperationNumber, string MisNumber, string MisRevision)>(
|
||||
"SELECT ItemNumber, OperationNumber, MisNumber, MisRevision FROM dbo.fn_GetSearchPartOperations(@SearchId)",
|
||||
new { SearchId = searchId });
|
||||
|
||||
// Assert
|
||||
results.Should().BeEmpty();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task fn_GetSearchPartOperations_SearchNotFound_ReturnsEmpty()
|
||||
{
|
||||
// Act
|
||||
var results = await Connection.QueryAsync<(string ItemNumber, string OperationNumber, string MisNumber, string MisRevision)>(
|
||||
"SELECT ItemNumber, OperationNumber, MisNumber, MisRevision FROM dbo.fn_GetSearchPartOperations(@SearchId)",
|
||||
new { SearchId = 99999 });
|
||||
|
||||
// Assert
|
||||
results.Should().BeEmpty();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task fn_GetSearchPartOperations_NullCriteria_ReturnsEmpty()
|
||||
{
|
||||
// Arrange
|
||||
var searchId = await InsertTestSearchWithRawCriteriaAsync(null);
|
||||
|
||||
// Act
|
||||
var results = await Connection.QueryAsync<(string ItemNumber, string OperationNumber, string MisNumber, string MisRevision)>(
|
||||
"SELECT ItemNumber, OperationNumber, MisNumber, MisRevision FROM dbo.fn_GetSearchPartOperations(@SearchId)",
|
||||
new { SearchId = searchId });
|
||||
|
||||
// Assert
|
||||
results.Should().BeEmpty();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task fn_GetSearchPartOperations_InvalidJson_ReturnsEmpty()
|
||||
{
|
||||
// Arrange
|
||||
var searchId = await InsertTestSearchWithRawCriteriaAsync("not valid json");
|
||||
|
||||
// Act
|
||||
var results = await Connection.QueryAsync<(string ItemNumber, string OperationNumber, string MisNumber, string MisRevision)>(
|
||||
"SELECT ItemNumber, OperationNumber, MisNumber, MisRevision FROM dbo.fn_GetSearchPartOperations(@SearchId)",
|
||||
new { SearchId = searchId });
|
||||
|
||||
// Assert
|
||||
results.Should().BeEmpty();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task fn_GetSearchPartOperations_PartialObjects_UsesNullForMissingColumns()
|
||||
{
|
||||
// Arrange - JSON with objects missing some properties
|
||||
var searchId = await InsertTestSearchWithRawCriteriaAsync(
|
||||
"{\"PartOperations\":[" +
|
||||
"{\"ItemNumber\":\"ITEM001\",\"OperationNumber\":\"10\"}," + // Missing MisNumber and MisRevision
|
||||
"{\"MisNumber\":\"MIS002\",\"MisRevision\":\"B\"}," + // Missing ItemNumber and OperationNumber
|
||||
"{\"ItemNumber\":\"ITEM003\",\"OperationNumber\":\"30\",\"MisNumber\":\"MIS003\",\"MisRevision\":\"C\"}" + // Complete
|
||||
"]}");
|
||||
|
||||
// Act
|
||||
var results = await Connection.QueryAsync<(string? ItemNumber, string? OperationNumber, string? MisNumber, string? MisRevision)>(
|
||||
"SELECT ItemNumber, OperationNumber, MisNumber, MisRevision FROM dbo.fn_GetSearchPartOperations(@SearchId)",
|
||||
new { SearchId = searchId });
|
||||
|
||||
// Assert
|
||||
var resultList = results.ToList();
|
||||
resultList.Should().HaveCount(3);
|
||||
resultList.Should().Contain(x => x.ItemNumber == "ITEM001" && x.OperationNumber == "10" && x.MisNumber == null && x.MisRevision == null);
|
||||
resultList.Should().Contain(x => x.ItemNumber == null && x.OperationNumber == null && x.MisNumber == "MIS002" && x.MisRevision == "B");
|
||||
resultList.Should().Contain(x => x.ItemNumber == "ITEM003" && x.OperationNumber == "30" && x.MisNumber == "MIS003" && x.MisRevision == "C");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task fn_GetSearchPartOperations_NullOptionalFields_ReturnsWithNulls()
|
||||
{
|
||||
// Arrange - using C# model with empty strings (which serialize to "")
|
||||
// The SQL function handles nulls/missing in JSON, so we test explicit null in JSON
|
||||
var searchId = await InsertTestSearchWithRawCriteriaAsync(
|
||||
"{\"PartOperations\":[" +
|
||||
"{\"ItemNumber\":\"ITEM001\",\"OperationNumber\":\"10\",\"MisNumber\":null,\"MisRevision\":null}" +
|
||||
"]}");
|
||||
|
||||
// Act
|
||||
var results = await Connection.QueryAsync<(string? ItemNumber, string? OperationNumber, string? MisNumber, string? MisRevision)>(
|
||||
"SELECT ItemNumber, OperationNumber, MisNumber, MisRevision FROM dbo.fn_GetSearchPartOperations(@SearchId)",
|
||||
new { SearchId = searchId });
|
||||
|
||||
// Assert
|
||||
var resultList = results.ToList();
|
||||
resultList.Should().HaveCount(1);
|
||||
var result = resultList.First();
|
||||
result.ItemNumber.Should().Be("ITEM001");
|
||||
result.OperationNumber.Should().Be("10");
|
||||
result.MisNumber.Should().BeNull();
|
||||
result.MisRevision.Should().BeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task fn_GetSearchPartOperations_SpecialCharacters_ReturnsCorrectly()
|
||||
{
|
||||
// Arrange
|
||||
var criteria = new SearchCriteria
|
||||
{
|
||||
PartOperations =
|
||||
[
|
||||
new PartOperationViewModel
|
||||
{
|
||||
ItemNumber = "ITEM-001",
|
||||
OperationNumber = "10A",
|
||||
MisNumber = "MIS.001",
|
||||
MisRevision = "A-1"
|
||||
}
|
||||
]
|
||||
};
|
||||
var searchId = await InsertTestSearchAsync(criteria);
|
||||
|
||||
// Act
|
||||
var results = await Connection.QueryAsync<(string ItemNumber, string OperationNumber, string MisNumber, string MisRevision)>(
|
||||
"SELECT ItemNumber, OperationNumber, MisNumber, MisRevision FROM dbo.fn_GetSearchPartOperations(@SearchId)",
|
||||
new { SearchId = searchId });
|
||||
|
||||
// Assert
|
||||
var resultList = results.ToList();
|
||||
resultList.Should().HaveCount(1);
|
||||
var result = resultList.First();
|
||||
result.ItemNumber.Should().Be("ITEM-001");
|
||||
result.OperationNumber.Should().Be("10A");
|
||||
result.MisNumber.Should().Be("MIS.001");
|
||||
result.MisRevision.Should().Be("A-1");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Additional Edge Case Tests
|
||||
|
||||
[Fact]
|
||||
public async Task fn_GetSearchComponentLots_LargeArray_ReturnsAll()
|
||||
{
|
||||
// Arrange
|
||||
var lots = Enumerable.Range(1, 100)
|
||||
.Select(i => new LotViewModel { LotNumber = $"LOT{i:D4}", ItemNumber = $"ITEM{i:D4}" })
|
||||
.ToList();
|
||||
var criteria = new SearchCriteria { ComponentLotNumbers = lots };
|
||||
var searchId = await InsertTestSearchAsync(criteria);
|
||||
|
||||
// Act
|
||||
var results = await Connection.QueryAsync<(string LotNumber, string ItemNumber)>(
|
||||
"SELECT LotNumber, ItemNumber FROM dbo.fn_GetSearchComponentLots(@SearchId)",
|
||||
new { SearchId = searchId });
|
||||
|
||||
// Assert
|
||||
results.Should().HaveCount(100);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task fn_GetSearchPartOperations_LargeArray_ReturnsAll()
|
||||
{
|
||||
// Arrange
|
||||
var operations = Enumerable.Range(1, 100)
|
||||
.Select(i => new PartOperationViewModel
|
||||
{
|
||||
ItemNumber = $"ITEM{i:D4}",
|
||||
OperationNumber = $"{i * 10}",
|
||||
MisNumber = $"MIS{i:D4}",
|
||||
MisRevision = $"R{i}"
|
||||
})
|
||||
.ToList();
|
||||
var criteria = new SearchCriteria { PartOperations = operations };
|
||||
var searchId = await InsertTestSearchAsync(criteria);
|
||||
|
||||
// Act
|
||||
var results = await Connection.QueryAsync<(string ItemNumber, string OperationNumber, string MisNumber, string MisRevision)>(
|
||||
"SELECT ItemNumber, OperationNumber, MisNumber, MisRevision FROM dbo.fn_GetSearchPartOperations(@SearchId)",
|
||||
new { SearchId = searchId });
|
||||
|
||||
// Assert
|
||||
results.Should().HaveCount(100);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task fn_GetSearchComponentLots_EmptyObject_ReturnsRowWithNulls()
|
||||
{
|
||||
// Arrange - JSON with empty object in array
|
||||
var searchId = await InsertTestSearchWithRawCriteriaAsync(
|
||||
"{\"ComponentLotNumbers\":[{}]}");
|
||||
|
||||
// Act
|
||||
var results = await Connection.QueryAsync<(string? LotNumber, string? ItemNumber)>(
|
||||
"SELECT LotNumber, ItemNumber FROM dbo.fn_GetSearchComponentLots(@SearchId)",
|
||||
new { SearchId = searchId });
|
||||
|
||||
// Assert
|
||||
var resultList = results.ToList();
|
||||
resultList.Should().HaveCount(1);
|
||||
resultList.First().LotNumber.Should().BeNull();
|
||||
resultList.First().ItemNumber.Should().BeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task fn_GetSearchPartOperations_EmptyObject_ReturnsRowWithNulls()
|
||||
{
|
||||
// Arrange - JSON with empty object in array
|
||||
var searchId = await InsertTestSearchWithRawCriteriaAsync(
|
||||
"{\"PartOperations\":[{}]}");
|
||||
|
||||
// Act
|
||||
var results = await Connection.QueryAsync<(string? ItemNumber, string? OperationNumber, string? MisNumber, string? MisRevision)>(
|
||||
"SELECT ItemNumber, OperationNumber, MisNumber, MisRevision FROM dbo.fn_GetSearchPartOperations(@SearchId)",
|
||||
new { SearchId = searchId });
|
||||
|
||||
// Assert
|
||||
var resultList = results.ToList();
|
||||
resultList.Should().HaveCount(1);
|
||||
var result = resultList.First();
|
||||
result.ItemNumber.Should().BeNull();
|
||||
result.OperationNumber.Should().BeNull();
|
||||
result.MisNumber.Should().BeNull();
|
||||
result.MisRevision.Should().BeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task fn_GetSearchComponentLots_LongValues_Truncated()
|
||||
{
|
||||
// Arrange - LotNumber is VARCHAR(30), ItemNumber is VARCHAR(128)
|
||||
var longLotNumber = new string('L', 50); // Will be truncated to 30
|
||||
var longItemNumber = new string('I', 200); // Will be truncated to 128
|
||||
var searchId = await InsertTestSearchWithRawCriteriaAsync(
|
||||
$"{{\"ComponentLotNumbers\":[{{\"LotNumber\":\"{longLotNumber}\",\"ItemNumber\":\"{longItemNumber}\"}}]}}");
|
||||
|
||||
// Act
|
||||
var results = await Connection.QueryAsync<(string LotNumber, string ItemNumber)>(
|
||||
"SELECT LotNumber, ItemNumber FROM dbo.fn_GetSearchComponentLots(@SearchId)",
|
||||
new { SearchId = searchId });
|
||||
|
||||
// Assert
|
||||
var resultList = results.ToList();
|
||||
resultList.Should().HaveCount(1);
|
||||
resultList.First().LotNumber.Should().HaveLength(30);
|
||||
resultList.First().ItemNumber.Should().HaveLength(128);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task fn_GetSearchPartOperations_LongValues_Truncated()
|
||||
{
|
||||
// Arrange - ItemNumber VARCHAR(128), OperationNumber/MisNumber/MisRevision VARCHAR(10)
|
||||
var longItemNumber = new string('I', 200); // Truncated to 128
|
||||
var longOperationNumber = new string('O', 20); // Truncated to 10
|
||||
var longMisNumber = new string('M', 20); // Truncated to 10
|
||||
var longMisRevision = new string('R', 20); // Truncated to 10
|
||||
var searchId = await InsertTestSearchWithRawCriteriaAsync(
|
||||
$"{{\"PartOperations\":[{{\"ItemNumber\":\"{longItemNumber}\",\"OperationNumber\":\"{longOperationNumber}\",\"MisNumber\":\"{longMisNumber}\",\"MisRevision\":\"{longMisRevision}\"}}]}}");
|
||||
|
||||
// Act
|
||||
var results = await Connection.QueryAsync<(string ItemNumber, string OperationNumber, string MisNumber, string MisRevision)>(
|
||||
"SELECT ItemNumber, OperationNumber, MisNumber, MisRevision FROM dbo.fn_GetSearchPartOperations(@SearchId)",
|
||||
new { SearchId = searchId });
|
||||
|
||||
// Assert
|
||||
var resultList = results.ToList();
|
||||
resultList.Should().HaveCount(1);
|
||||
var result = resultList.First();
|
||||
result.ItemNumber.Should().HaveLength(128);
|
||||
result.OperationNumber.Should().HaveLength(10);
|
||||
result.MisNumber.Should().HaveLength(10);
|
||||
result.MisRevision.Should().HaveLength(10);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
Reference in New Issue
Block a user