using System.Text.Json;
using FluentAssertions;
using foodmarket.Domain.Registry;
using foodmarket.Infrastructure.Persistence;
using foodmarket.Infrastructure.Registry;
using foodmarket.IntegrationTests.Support;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Xunit;
namespace foodmarket.IntegrationTests;
/// Копия «Реестра товаров» в каталог магазина должна помечать первый
/// штрихкод «Основным» (IsPrimary). Товар с единственным штрихкодом раньше
/// оставался без «Основного» (баг, fix #7).
[Collection(ApiCollection.Name)]
public class RegistryCopyPrimaryBarcodeTests
{
private readonly ApiFactory _factory;
public RegistryCopyPrimaryBarcodeTests(ApiFactory factory) => _factory = factory;
private static string RandomBarcode()
=> string.Concat(Enumerable.Range(0, 13).Select(_ => Random.Shared.Next(0, 10)));
[Fact]
public async Task Copy_sets_single_barcode_as_primary()
{
var api = new ApiActor(_factory.CreateClient());
var slug = $"regcopy-{Guid.NewGuid():N}";
await api.SignupAndLoginAsync(slug);
var settings = await api.GetJsonAsync("/api/organization/settings");
var orgId = Guid.Parse(settings.GetProperty("id").GetString()!);
var barcode = RandomBarcode();
var cardName = $"REG-{slug}";
// Готовим карточку реестра с ОДНИМ штрихкодом и запускаем копию напрямую
// (Hangfire в тестах выключен, поэтому зовём сервис сами).
using (var scope = _factory.Services.CreateScope())
{
var db = scope.ServiceProvider.GetRequiredService();
var unitId = await db.UnitsOfMeasure.AsNoTracking().Select(u => u.Id).FirstAsync();
db.ProductRegistryCards.Add(new ProductRegistryCard
{
Name = cardName,
UnitOfMeasureId = unitId,
Cost = 100m,
PurchasePrice = 100m,
RetailPrice = 150m,
Source = RegistryCardSource.Shop,
Barcodes = new List { new() { Code = barcode } },
});
await db.SaveChangesAsync();
// Регистрация выставила RegistryCopyState=1; копия отработает.
var svc = scope.ServiceProvider.GetRequiredService();
await svc.CopyRegistryToOrgAsync(orgId, default);
}
// Находим скопированный товар по штрихкоду и проверяем «Основной».
var found = await api.GetJsonAsync($"/api/catalog/products?pageSize=50&search={cardName}");
var items = found.TryGetProperty("items", out var it) ? it : found;
var product = items.EnumerateArray()
.FirstOrDefault(p => p.GetProperty("name").GetString() == cardName);
product.ValueKind.Should().Be(JsonValueKind.Object, "товар из реестра скопирован в каталог");
var detail = await api.GetJsonAsync($"/api/catalog/products/{product.GetProperty("id").GetString()}");
var barcodes = detail.GetProperty("barcodes").EnumerateArray().ToList();
barcodes.Should().ContainSingle(b => b.GetProperty("code").GetString() == barcode);
barcodes.Count(b => b.GetProperty("isPrimary").GetBoolean()).Should().Be(1, "ровно один штрихкод — «Основной»");
barcodes.Single(b => b.GetProperty("code").GetString() == barcode)
.GetProperty("isPrimary").GetBoolean().Should().BeTrue("единственный штрихкод должен быть «Основным»");
}
}