using JdeScoping.ExcelIO.Parsing; using Microsoft.Extensions.Logging.Abstractions; using NPOI.XSSF.UserModel; using Shouldly; using Xunit; namespace JdeScoping.ExcelIO.Tests.Parsing; public class ExcelParserServiceTests { private readonly ExcelParserService _service = new(NullLogger.Instance); [Fact] public void ParseWorkOrders_ReturnsWorkOrderNumbers() { var excelData = CreateWorkOrderExcel([12345, 67890, 11111]); using var stream = new MemoryStream(excelData); var result = _service.ParseWorkOrders(stream); result.Count.ShouldBe(3); result.ShouldContain(12345); result.ShouldContain(67890); result.ShouldContain(11111); } [Fact] public void ParseWorkOrders_SkipsInvalidNumbers() { using var workbook = new XSSFWorkbook(); var worksheet = workbook.CreateSheet("Sheet1"); worksheet.CreateRow(0).CreateCell(0).SetCellValue("Work Order"); worksheet.CreateRow(1).CreateCell(0).SetCellValue("12345"); worksheet.CreateRow(2).CreateCell(0).SetCellValue("not-a-number"); worksheet.CreateRow(3).CreateCell(0).SetCellValue("67890"); using var ms = new MemoryStream(); workbook.Write(ms, leaveOpen: true); ms.Position = 0; var result = _service.ParseWorkOrders(ms); result.Count.ShouldBe(2); } [Fact] public void ParseItems_ReturnsItemNumbers() { var excelData = CreateItemExcel(["ITEM-001", "ITEM-002"]); using var stream = new MemoryStream(excelData); var result = _service.ParseItems(stream); result.Count.ShouldBe(2); result.ShouldContain("ITEM-001"); result.ShouldContain("ITEM-002"); } [Fact] public void ParseComponentLots_ReturnsLotViewModels() { var excelData = CreateComponentLotExcel([("LOT001", "ITEM-001"), ("LOT002", "ITEM-002")]); using var stream = new MemoryStream(excelData); var result = _service.ParseComponentLots(stream); result.Count.ShouldBe(2); result[0].LotNumber.ShouldBe("LOT001"); result[0].ItemNumber.ShouldBe("ITEM-001"); } [Fact] public void ParsePartOperations_ReturnsPartOperations() { var excelData = CreatePartOperationExcel([("ITEM-001", "100", "MIS001", "A")]); using var stream = new MemoryStream(excelData); var result = _service.ParsePartOperations(stream); result.Count.ShouldBe(1); result[0].ItemNumber.ShouldBe("ITEM-001"); result[0].OperationNumber.ShouldBe("100"); result[0].MisNumber.ShouldBe("MIS001"); result[0].MisRevision.ShouldBe("A"); } [Fact] public void ParsePartOperations_TruncatesDecimalOperationNumbers() { var excelData = CreatePartOperationExcel([("ITEM-001", "100.5", "MIS001", "A")]); using var stream = new MemoryStream(excelData); var result = _service.ParsePartOperations(stream); result[0].OperationNumber.ShouldBe("100"); } private static byte[] CreateWorkOrderExcel(long[] workOrderNumbers) { using var workbook = new XSSFWorkbook(); var worksheet = workbook.CreateSheet("Sheet1"); worksheet.CreateRow(0).CreateCell(0).SetCellValue("Work Order Number"); for (var i = 0; i < workOrderNumbers.Length; i++) { worksheet.CreateRow(i + 1).CreateCell(0).SetCellValue(workOrderNumbers[i]); } using var stream = new MemoryStream(); workbook.Write(stream, leaveOpen: true); return stream.ToArray(); } private static byte[] CreateItemExcel(string[] itemNumbers) { using var workbook = new XSSFWorkbook(); var worksheet = workbook.CreateSheet("Sheet1"); worksheet.CreateRow(0).CreateCell(0).SetCellValue("Item Number"); for (var i = 0; i < itemNumbers.Length; i++) { worksheet.CreateRow(i + 1).CreateCell(0).SetCellValue(itemNumbers[i]); } using var stream = new MemoryStream(); workbook.Write(stream, leaveOpen: true); return stream.ToArray(); } private static byte[] CreateComponentLotExcel((string LotNumber, string ItemNumber)[] lots) { using var workbook = new XSSFWorkbook(); var worksheet = workbook.CreateSheet("Sheet1"); var header = worksheet.CreateRow(0); header.CreateCell(0).SetCellValue("Lot Number"); header.CreateCell(1).SetCellValue("Item Number"); for (var i = 0; i < lots.Length; i++) { var row = worksheet.CreateRow(i + 1); row.CreateCell(0).SetCellValue(lots[i].LotNumber); row.CreateCell(1).SetCellValue(lots[i].ItemNumber); } using var stream = new MemoryStream(); workbook.Write(stream, leaveOpen: true); return stream.ToArray(); } private static byte[] CreatePartOperationExcel((string ItemNumber, string OpNumber, string MisNumber, string MisRevision)[] operations) { using var workbook = new XSSFWorkbook(); var worksheet = workbook.CreateSheet("Sheet1"); var header = worksheet.CreateRow(0); header.CreateCell(0).SetCellValue("Item Number"); header.CreateCell(1).SetCellValue("Operation Number"); header.CreateCell(2).SetCellValue("MIS Number"); header.CreateCell(3).SetCellValue("MIS Revision"); for (var i = 0; i < operations.Length; i++) { var row = worksheet.CreateRow(i + 1); row.CreateCell(0).SetCellValue(operations[i].ItemNumber); row.CreateCell(1).SetCellValue(operations[i].OpNumber); row.CreateCell(2).SetCellValue(operations[i].MisNumber); row.CreateCell(3).SetCellValue(operations[i].MisRevision); } using var stream = new MemoryStream(); workbook.Write(stream, leaveOpen: true); return stream.ToArray(); } }