using System.Text.Json;
using FluentAssertions;
using foodmarket.Shared.Pos.V1;
using Xunit;
namespace foodmarket.UnitTests;
/// Контракт POS — public API: ломая его, мы ломаем все Windows-кассы
/// в поле. Тестируем сериализацию round-trip + наличие required-полей.
/// При попытке убрать поле или поменять тип компиляция этих тестов упадёт.
public class PosContractsTests
{
[Fact]
public void Product_sync_dto_round_trips()
{
var dto = new ProductSyncDto
{
Id = Guid.NewGuid(),
Name = "Молоко 1л",
Article = "M-001",
Barcodes = new[] { "1234567890123", "2345678901234" },
UnitCode = "л",
Packaging = 1,
VatPercent = 12m,
VatEnabled = true,
IsMarked = false,
IsArchived = false,
UpdatedAt = DateTime.UtcNow,
};
var json = JsonSerializer.Serialize(dto);
var back = JsonSerializer.Deserialize(json)!;
back.Should().BeEquivalentTo(dto);
}
[Fact]
public void Batch_dto_carries_idempotency_key()
{
var batch = new PosSaleBatchDto
{
IdempotencyKey = Guid.NewGuid(),
Sales = new[]
{
new PosSaleDto
{
ClientSaleId = Guid.NewGuid(),
OccurredAt = DateTime.UtcNow,
Payment = 0, PaidCash = 1000m, PaidCard = 0m,
Lines = new[]
{
new PosSaleLineDto
{
ProductId = Guid.NewGuid(), Quantity = 1m,
UnitPrice = 1000m, Discount = 0m, VatPercent = 12m,
},
},
},
},
};
var json = JsonSerializer.Serialize(batch);
var back = JsonSerializer.Deserialize(json)!;
back.IdempotencyKey.Should().Be(batch.IdempotencyKey);
back.Sales.Should().HaveCount(1);
back.Sales[0].Lines.Should().HaveCount(1);
}
[Fact]
public void Sync_response_collects_all_groups()
{
var resp = new PosSyncResponse
{
ServerTime = DateTime.UtcNow,
Products = Array.Empty(),
Prices = Array.Empty(),
Stocks = Array.Empty(),
Counterparties = Array.Empty(),
DeletedProductIds = Array.Empty(),
};
var json = JsonSerializer.Serialize(resp);
var back = JsonSerializer.Deserialize(json)!;
back.Should().BeEquivalentTo(resp);
}
}