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("единственный штрихкод должен быть «Основным»"); } }