Files
Ai/TrafagSalesExporter/TrafagSalesExporter.Tests/ExportAuditCsvServiceTests.cs
T

176 lines
6.4 KiB
C#

using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using TrafagSalesExporter.Data;
using TrafagSalesExporter.Models;
using TrafagSalesExporter.Services;
namespace TrafagSalesExporter.Tests;
public sealed class ExportAuditCsvServiceTests : IDisposable
{
private readonly string _tempDirectory;
public ExportAuditCsvServiceTests()
{
_tempDirectory = Path.Combine("C:\\TMP", $"trafag-audit-csv-tests-{Guid.NewGuid():N}");
Directory.CreateDirectory(_tempDirectory);
}
public void Dispose()
{
if (Directory.Exists(_tempDirectory))
Directory.Delete(_tempDirectory, recursive: true);
}
[Fact]
public async Task WriteSiteAuditCsvAsync_Roundtrips_Transformed_SalesRecord()
{
var service = new ExportAuditCsvService();
var settings = new ExportSettings
{
AuditCsvEnabled = true,
LocalAuditCsvFolder = _tempDirectory
};
var site = new Site { TSC = "TRCH", Land = "Schweiz" };
var record = new SalesRecord
{
SourceSystem = "SAP",
ExtractionDate = new DateTime(2026, 6, 11, 8, 30, 0, DateTimeKind.Utc),
Tsc = "TRCH",
SourceLineId = "line-1",
DocumentEntry = 42,
InvoiceNumber = "INV-1",
PositionOnInvoice = 7,
Material = "MAT;1",
Name = "Artikel \"Audit\"",
ProductDivisionCode = "0001",
ProductDivisionText = "Pressure",
ProductMappingAssigned = "TRUE",
Quantity = 2.5m,
SalesPriceValue = 1234.56m,
SalesCurrency = "CHF",
DocumentCurrency = "EUR",
DocumentTotalForeignCurrency = 1300m,
DocumentTotalLocalCurrency = 1234.56m,
VatSumForeignCurrency = 0m,
VatSumLocalCurrency = 0m,
DocumentRate = 0.95m,
CompanyCurrency = "CHF",
PostingDate = new DateTime(2026, 6, 10),
InvoiceDate = new DateTime(2026, 6, 11),
Land = "Schweiz",
DocumentType = "INV"
};
var path = await service.WriteSiteAuditCsvAsync(site, settings, "SAP", _tempDirectory, [record]);
Assert.True(File.Exists(path));
var records = await service.ReadLatestSiteAuditCsvRecordsAsync(settings);
var roundtrip = Assert.Single(records);
Assert.Equal("SAP", roundtrip.SourceSystem);
Assert.Equal("TRCH", roundtrip.Tsc);
Assert.Equal("line-1", roundtrip.SourceLineId);
Assert.Equal("MAT;1", roundtrip.Material);
Assert.Equal("Artikel \"Audit\"", roundtrip.Name);
Assert.Equal(1234.56m, roundtrip.SalesPriceValue);
Assert.Equal("CHF", roundtrip.SalesCurrency);
Assert.Equal(new DateTime(2026, 6, 10), roundtrip.PostingDate);
Assert.Equal(new DateTime(2026, 6, 11), roundtrip.InvoiceDate);
}
[Fact]
public async Task CentralSalesDataProvider_Uses_AuditCsv_When_Configured()
{
var csvService = new ExportAuditCsvService();
await csvService.WriteSiteAuditCsvAsync(
new Site { TSC = "TRUK", Land = "England" },
new ExportSettings { AuditCsvEnabled = true, LocalAuditCsvFolder = _tempDirectory },
"MANUAL_EXCEL",
_tempDirectory,
[
new SalesRecord
{
SourceSystem = "MANUAL_EXCEL",
ExtractionDate = new DateTime(2026, 6, 11),
Tsc = "TRUK",
Land = "England",
InvoiceNumber = "UK-1",
SalesPriceValue = 10m,
SalesCurrency = "GBP",
InvoiceDate = new DateTime(2026, 1, 1)
}
]);
await using var connection = new SqliteConnection("DataSource=:memory:");
await connection.OpenAsync();
var options = new DbContextOptionsBuilder<AppDbContext>()
.UseSqlite(connection)
.Options;
await using (var db = new AppDbContext(options))
{
await db.Database.EnsureCreatedAsync();
db.ExportSettings.Add(new ExportSettings
{
UseAuditCsvAsCentralSource = true,
LocalAuditCsvFolder = _tempDirectory
});
db.Sites.Add(new Site
{
Id = 1,
Schema = "DB",
TSC = "TRDB",
Land = "DB",
SourceSystem = "DB",
IsActive = true
});
db.CentralSalesRecords.Add(new CentralSalesRecord
{
StoredAtUtc = DateTime.UtcNow,
SiteId = 1,
SourceSystem = "DB",
ExtractionDate = new DateTime(2026, 6, 11),
Tsc = "TRDB",
InvoiceNumber = "DB-1",
Land = "DB",
DocumentType = "INV"
});
await db.SaveChangesAsync();
}
var dbFactory = new TestDbContextFactory(options);
var centralService = new CentralSalesRecordService(dbFactory, new NullAppEventLogService());
var provider = new CentralSalesDataProvider(dbFactory, centralService, csvService);
var records = await provider.GetRecordsAsync();
var record = Assert.Single(records);
Assert.Equal("TRUK", record.Tsc);
Assert.Equal("UK-1", record.InvoiceNumber);
Assert.Equal(10m, record.SalesPriceValue);
}
private sealed class NullAppEventLogService : IAppEventLogService
{
public Task WriteAsync(string category, string message, string level = "Info", int? siteId = null, string? land = null, string? details = null)
=> Task.CompletedTask;
public Task WriteDebugAsync(string category, string message, int? siteId = null, string? land = null, string? details = null)
=> Task.CompletedTask;
}
private sealed class TestDbContextFactory : IDbContextFactory<AppDbContext>
{
private readonly DbContextOptions<AppDbContext> _options;
public TestDbContextFactory(DbContextOptions<AppDbContext> options)
{
_options = options;
}
public AppDbContext CreateDbContext() => new(_options);
public Task<AppDbContext> CreateDbContextAsync(CancellationToken cancellationToken = default)
=> Task.FromResult(new AppDbContext(_options));
}
}