using System.Net;
using System.Net.Http.Json;
using System.Text.Json;
using FluentAssertions;
using foodmarket.IntegrationTests.Support;
using Xunit;
namespace foodmarket.IntegrationTests;
/// Регрессия на шум в логах stage-api: раньше
/// определял «уже сидировано»
/// по наличию Product с Article LIKE 'DEMO-%'. После того как «Демо-магазин»
/// на стенде наполнили реальным каталогом из МойСклада (не с префиксом DEMO-),
/// маркер срабатывал false — сидер шёл заново и падал на unique-индексе
/// IX_product_barcodes_OrganizationId_Code (23505) при каждом рестарте.
/// Фикс расширил маркер до «любой Product в орге». Тесты фиксируют:
/// 1) повторный Seed на орге с товарами не пишет и не падает;
/// 2) org с собственным (не-DEMO) каталогом тоже защищена.
[Collection(ApiCollection.Name)]
public class DemoSeederIdempotencyTests
{
private readonly ApiFactory _factory;
public DemoSeederIdempotencyTests(ApiFactory factory) => _factory = factory;
[Fact]
public async Task SeedDemo_second_call_on_populated_org_returns_already_seeded()
{
// Фоновый сценарий: Admin впервые вызвал seed-demo (50 товаров DEMO-*),
// перезапуск или повторное нажатие не должны дёрнуть вставку второй раз.
var a = new ApiActor(_factory.CreateClient());
await a.SignupAndLoginAsync($"seed-twice-{Guid.NewGuid():N}");
using var first = await a.Http.PostAsync("/api/admin/seed-demo", content: null);
first.StatusCode.Should().Be(HttpStatusCode.OK);
var firstBody = await first.Content.ReadFromJsonAsync();
firstBody.GetProperty("alreadySeeded").GetBoolean().Should().BeFalse();
firstBody.GetProperty("products").GetInt32().Should().Be(50);
using var second = await a.Http.PostAsync("/api/admin/seed-demo", content: null);
second.StatusCode.Should().Be(HttpStatusCode.OK);
var secondBody = await second.Content.ReadFromJsonAsync();
secondBody.GetProperty("alreadySeeded").GetBoolean().Should().BeTrue();
// Количество товаров не выросло — повторная вставка не произошла.
secondBody.GetProperty("products").GetInt32().Should().Be(50);
}
[Fact]
public async Task SeedDemo_on_org_with_imported_catalog_skips_without_duplicate_barcode()
{
// Главная регрессия: воспроизводит stage-сценарий, где у организации уже
// есть товары БЕЗ префикса DEMO-. Старый маркер (Article LIKE 'DEMO-%')
// пропускал гард и сидер падал на unique-индексе по баркодам (23505).
var a = new ApiActor(_factory.CreateClient());
await a.SignupAndLoginAsync($"seed-imported-{Guid.NewGuid():N}");
var refs = await a.LoadRefsAsync();
// Один товар с «импортным» (не DEMO-*) артикулом — имитирует каталог
// из МойСклада. Этого хватает чтобы новый маркер «any Product» сработал.
await a.CreateProductAsync(refs, $"ImportedProduct-{Guid.NewGuid():N}",
retailPrice: 500m, barcode: $"IMP-{Guid.NewGuid():N}");
using var resp = await a.Http.PostAsync("/api/admin/seed-demo", content: null);
resp.StatusCode.Should().Be(HttpStatusCode.OK, "сидер должен no-op'нуть, а не упасть с 500");
var body = await resp.Content.ReadFromJsonAsync();
body.GetProperty("alreadySeeded").GetBoolean().Should().BeTrue();
// Должен быть ровно 1 товар — тот что мы создали; никаких DEMO- вставок.
body.GetProperty("products").GetInt32().Should().Be(1);
// Status (Peek) тоже отражает «заселено» — чтобы UI не предлагал кнопку.
var status = await a.GetJsonAsync("/api/admin/seed-demo/status");
status.GetProperty("alreadySeeded").GetBoolean().Should().BeTrue();
}
}