using ImageCatalog_2.Services; using ImageCatalog_2.Models; using Shouldly; using System.Text; namespace MaddoShared.Tests; [TestClass] public sealed class AiExtractionServiceCsvTests { [TestMethod] public void WriteCsvOutput_UsesLegacyCompatibleQuotingAndSkipsEmptyResults() { using var tempDir = new TempDirectory(); var csvPath = Path.Combine(tempDir.Path, "ocr.csv"); AiExtractionService.WriteCsvOutput( csvPath, [ new AiResultItem { Path = @"C:\images\IMG_7146.JPG", Text = "43" }, new AiResultItem { Path = @"C:\images\IMG_7207.JPG", Text = "43,84,61" }, new AiResultItem { Path = @"C:\images\IMG_7208.JPG", Text = string.Empty }, new AiResultItem { Path = @"C:\images\IMG_7209.JPG", Text = " " }, new AiResultItem { Path = @"C:\images\IMG_7210.JPG", Text = "a\"b,c" } ]); var csv = File.ReadAllText(csvPath, Encoding.UTF8); csv.ShouldBe("filename,text\r" + "IMG_7146.JPG,43\r" + "IMG_7207.JPG,\"43,84,61\"\r" + "IMG_7210.JPG,\"a\"\"b,c\"\r"); } [TestMethod] public void WriteCsvOutput_WritesUtf8WithoutBom() { using var tempDir = new TempDirectory(); var csvPath = Path.Combine(tempDir.Path, "ocr.csv"); AiExtractionService.WriteCsvOutput( csvPath, [new AiResultItem { Path = @"C:\images\IMG_7146.JPG", Text = "43" }]); var bytes = File.ReadAllBytes(csvPath); bytes[.."filename,text\r".Length].ShouldBe(Encoding.ASCII.GetBytes("filename,text\r")); bytes[..3].ShouldNotBe(new byte[] { 0xEF, 0xBB, 0xBF }); } private sealed class TempDirectory : IDisposable { public TempDirectory() { Path = System.IO.Path.Combine(System.IO.Path.GetTempPath(), System.IO.Path.GetRandomFileName()); Directory.CreateDirectory(Path); } public string Path { get; } public void Dispose() { if (Directory.Exists(Path)) { Directory.Delete(Path, recursive: true); } } } }